#TODO: Fix all of this!!!
from coffeetalk.protocol import ioelement, iotypes
        
class Simple(object):
            
    def __init__(self,name='Access',user='',group='',permissions='---------',element=None):

        self.name = name
        
        self.user = user
        self.group = group
        self.permissions = permissions
        
        self.userread = False
        self.userwrite = False
        self.usersubscribe = False
        self.groupread = False
        self.groupwrite = False
        self.groupsubscribe = False
        self.othersread = False
        self.otherswrite = False
        self.otherssubscribe = False
        
        if element is not None:
            self._from_element(element)
                    
        if self.permissions[0:1] == 'r':
            self.userread = True
        if self.permissions[1:2] == 'w':
            self.userwrite = True
        if self.permissions[2:3] == 's':
            self.usersubscribe = True
        if self.permissions[3:4] == 'r':
            self.groupread = True
        if self.permissions[4:5] == 'w':
            self.groupwrite = True
        if self.permissions[5:6] == 's':
            self.groupsubscribe = True
        if self.permissions[6:7] == 'r':
            self.othersread = True
        if self.permissions[7:8] == 'w':
            self.otherswrite = True
        if self.permissions[8:9] == 's':
            self.otherssubscribe = True
            
    def _from_element(self,element):
        self.user = element.attribs['user']
        self.group = element.attribs['group']
        self.permissions = element.attribs['permissions']
    
    def __str__(self):
        return str(self._to_element())
    def _to_element(self):
        
        return ioelement.IOElement('Access',{'type':'coffeetalk.protocol.access.Simple','user':self.user,'group':self.group,'permissions':self.permissions})
    
    def check_readaccess(self,env):
        
        if env is None: return False

        if env.group == 'Internal':
            return True

        user = env.username
        group = env.group
        
        if user == self.user and self.userread == True:
            return True
        if group == self.group and self.groupread == True:
            return True
        if self.othersread == True:
            return True
        
        return False
    
    def check_writeaccess(self,env):
        
        if env is None: return False
        
        if env.group == 'Internal':
            return True

        user = env.username
        group = env.group
        
        if user == self.user and self.userwrite == True:
            return True
        if group == self.group and self.groupwrite == True:
            return True
        if self.otherswrite == True:
            return True
        
        return False
    
    def check_subscribeaccess(self,env):
        
        if env is None: return False
        
        if env.group == 'Internal':
            return True

        user = env.username
        group = env.group
        
        if user == self.user and self.usersubscribe == True:
            return True
        if group == self.group and self.groupsubscribe == True:
            return True
        if self.otherssubscribe == True:
            return True
        
        return False
    
class Extended(object):
    
    def __init__(self,name='Access'):
        
        self.name = name
        
        self.Users = iotypes.IOList(name='Users',require='coffeetalk.protocol.access.User')
        self.Groups = iotypes.IOList(name='Groups',require='coffeetalk.protocol.access.Group')
        self.Others = Others()
        
        self.accesselement = ioelement.IOElement('Access',{})
        self.accesselement.add(ioelement.IOElement('Users',{}))
        self.accesselement.add(ioelement.IOElement('Groups',{}))
        self.accesselement.add(Others())
    
    def __str__(self):
        return str(self._to_element())
    
    def _to_element(self):
        returnelement = ioelement.IOElement('Access',{'type':'coffeetalk.protocol.access.Extended'})
        returnelement.add(self.Users._to_element())
        returnelement.add(self.Groups._to_element())
        returnelement.add(self.Others._to_element())
        
        return returnelement
    
    def from_simple(self,simpleobject):
        
        username = simpleobject.user
        group = simpleobject.group
        
        newuser = User(name=username,permissions=simpleobject.permissions[0:3])
        
        newgroup = Group(name=group,permissions=simpleobject.permissions[3:6])
                
        others = Others()
        others.userread = simpleobject.othersread
        others.userwrite = simpleobject.otherswrite
        others.subscribe = simpleobject.otherssubscribe
        
        self.add_user(newuser)
        self.add_group(newgroup)
        self.add_others(others)
        
    def add_access(self,accessobject):
        
        if isinstance(accessobject,User):
            self.add_user(accessobject)
        elif isinstance(accessobject,Group):
            self.add_group(accessobject)
        elif isinstance(accessobject,Others):
            self.add_others(accessobject)
    
    def remove_access(self,accesskey):
        # Return True if the key exists and is deleted
        if self.Users.has_key(accesskey):
            del self.Users[accesskey]
            return True
        elif self.Groups.has_key(accesskey):
            del self.Groups[accesskey]
            return True
        return False
        
    def add_user(self,userelement):
        if isinstance(userelement,User):
            self.Users[userelement.name] = userelement
    
    def remove_user(self,username):
        if self.Users.has_key(username):
            del self.Users[username]
    
    def add_group(self,groupelement):
        if isinstance(groupelement,Group):
            self.Groups[groupelement.name] = groupelement
    
    def remove_group(self,groupname):
        if self.Groups.has_key(groupname):
            del self.Groups[groupname]
            
    def add_others(self,otherselement):
        if isinstance(otherselement,Others):
            self.Others = otherselement
    
    def check_readaccess(self,env):
        
        if env is None: return False
        
        if self.Users.has_key(env.username):
            checkelement = self.Users[env.username]
            return checkelement.check_readaccess(env)
        elif self.Groups.has_key(env.group):
            checkelement = self.Groups[env.group]
            return checkelement.check_readaccess(env)
        else:
            return self.Others.check_readaccess(env)
            
    def check_writeaccess(self,env):
        
        if env is None: return False
        
        if self.Users.has_key(env.username):
            checkelement = self.Users[env.username]
            return checkelement.check_writeaccess(env)
        elif self.Groups.has_key(env.group):
            checkelement = self.Groups[env.group]
            return checkelement.check_writeaccess(env)
        else:
            return self.Others.check_writeaccess(env)
    
    def check_subscribeaccess(self,env):
        
        if env is None: return False
        
        if self.Users.has_key(env.username):
            checkelement = self.Users[env.username]
            return checkelement.check_subscribeaccess(env)
        elif self.Groups.has_key(env.group):
            checkelement = self.Groups[env.group]
            return checkelement.check_subscribeaccess(env)
        else:
            return self.Others.check_subscribeaccess(env)
       
class User(object):
    
    _type = 'coffeetalk.protocol.access.User'
    def __init__(self,name='User',permissions='---'):
        
        try:
            if len(permissions) != 3:
                raise
            self.user = name
            self.permissions = permissions
            
            self.userread = False
            self.userwrite = False
            self.usersubscribe = False
            
            if self.permissions[0:1] == 'r':
                self.userread = True
            if self.permissions[1:2] == 'w':
                self.userwrite = True 
            if self.permissions[2:3] == 's':
                self.usersubscribe = True
            
            self.name = self.user    
        except:
            raise AttributeError('Invalid coffeetalk.protocol.access.User')
    
    def __str__(self):
        return str(self._to_element())
    
    def _to_element(self):
        return ioelement.IOElement(self.name,{'type':'coffeetalk.protocol.access.User','permissions':self.permissions})
        
    def check_readaccess(self,env):
        
        if env is None: return False
        
        if env.group == 'Internal':
            return True

        user = env.username
                
        if user == self.user and self.userread == True:
            return True
        
        return False
    
    def check_writeaccess(self,env):
        
        if env is None: return False
        
        if env.group == 'Internal':
            return True

        user = env.username
               
        if user == self.user and self.userwrite == True:
            return True
                
        return False
    
    def check_subscribeaccess(self,env):
        
        if env is None: return False
        
        if env.group == 'Internal':
            return True

        user = env.username
               
        if user == self.user and self.usersubscribe == True:
            return True
                
        return False
    
class Group:
    _type = 'coffeetalk.protocol.access.Group'
    def __init__(self,name='Group',permissions='---'):
        
        try:
            if len(permissions) != 3:
                raise
            self.group = name
            self.permissions = permissions
            
            self.groupread = False
            self.groupwrite = False
            self.groupsubscribe = False
            
            if self.permissions[0:1] == 'r':
                self.groupread = True
            if self.permissions[1:2] == 'w':
                self.groupwrite = True
            if self.permissions[2:3] == 's':
                self.groupsubscribe = True
            self.name = self.group           
        except:
            raise AttributeError('Invalid coffeetalk.protocol.access.Group')
    
    def __str__(self):
        return str(self._to_element())
    
    def _to_element(self):
        return ioelement.IOElement(self.name,{'type':'coffeetalk.protocol.access.Group','permissions':self.permissions})
       
    def check_readaccess(self,env):
        
        if env is None: return False
        
        if env.group == 'Internal':
            return True

        group = env.group
        
        if group == self.group and self.groupread == True:
            return True
               
        return False
    
    def check_writeaccess(self,env):
        
        if env is None: return False
        
        if env.group == 'Internal':
            return True

        group = env.group
        
        if group == self.group and self.groupwrite == True:
            return True
        
        return False
    
    def check_subscribeaccess(self,env):
        
        if env is None: return False
        
        if env.group == 'Internal':
            return True

        group = env.group
        
        if group == self.group and self.groupsubscribe == True:
            return True
        
        return False
    
class Others:
    _type = 'coffeetalk.protocol.access.Others'
    def __init__(self,name='Others',permissions='---'):
        
        self.name = name
        try:
            
            self.permissions = permissions
            
            if len(permissions) != 3:
                raise
            self.userread = False
            self.userwrite = False
            self.usersubscribe = False
            
            if self.permissions[0:1] == 'r':
                self.userread = True
            if self.permissions[1:2] == 'w':
                self.userwrite = True
            if self.permissions[2:3] == 's':
                self.usersubscribe = True
                 
           
        except:
            raise AttributeError('Invalid coffeetalk.protocol.access.Others')
    
    def __str__(self):
        return str(self._to_element())
    
    def _to_element(self):
        return ioelement.IOElement(self.name,{'type':'coffeetalk.protocol.access.Others','permissions':self.permissions})
        
    def check_readaccess(self,env):
        
        if env is None: return False
        
        if env.group == 'Internal':
            return True
                
        if self.userread == True:
            return True
        
        return False
    
    def check_writeaccess(self,env):
        
        if env is None: return False
        
        if env.group == 'Internal':
            return True
               
        if self.userwrite == True:
            return True
                
        return False
    
    def check_subscribeaccess(self,env):
        
        if env is None: return False
        
        if env.group == 'Internal':
            return True
               
        if self.usersubscribe == True:
            return True
                
        return False

